fix(fmt): JSX <pre> with comments now formats stably#34556
Open
divybot wants to merge 2 commits into
Open
Conversation
bartlomieju
requested changes
Jun 1, 2026
bartlomieju
left a comment
Member
There was a problem hiding this comment.
We can't merge it until the dprint-plugin-typescript is released
d2eb0bd to
9916c5e
Compare
`deno fmt` panics with `Formatting not stable. Bailed after 5 tries` when a
`<pre>` JSX element contains a `{/* … */}` expression-container comment, e.g.
```tsx
function ErrorPage500(props: ErrorPageProps) {
return (
<pre>
{props.url}
{/* {props.url} */}
</pre>
);
}
```
`<pre>` element bodies in `dprint-plugin-typescript` are emitted verbatim as
raw text instead of going through the normal JSX child generation path. That
bypass skips the bookkeeping that marks comments inside the body as handled,
so when `gen_node` is later called for `</pre>` the comment is picked up
again as a leading comment of the closing tag and emitted as a JS block
comment outside the expression container. Each formatting pass adds one
more copy of the comment, so the formatter never stabilises.
The fix is in `dprint-plugin-typescript`
(dprint/dprint-plugin-typescript#796) and is consumed here via a
`[patch.crates-io]` git entry until the upstream change ships in a new
crates.io release. A spec regression test in
`tests/specs/fmt/jsx_pre_with_comment` uses the exact input from the issue
and asserts the formatter produces the same text back.
Closes #20403
Closes denoland/orchid#300
Co-Authored-By: Divy Srivastava <me@littledivy.com>
9916c5e to
baf0f0f
Compare
`tests/specs/mod.rs` panics if an inline `output` string exceeds 160 characters, so the spec test for the JSX `<pre>` comment regression failed on every platform with "The 'output' property in your __test__.jsonc file is too long." Extract the expected text into `expected.out` and reference it from `__test__.jsonc`. Co-Authored-By: Divy Srivastava <me@littledivy.com>
baf0f0f to
d795829
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
deno fmtpanics withFormatting not stable. Bailed after 5 trieswhen a<pre>JSX element contains a{/* … */}expression-container comment. The minimal repro from #20403 is:Each formatting pass duplicates the comment outside the JSX expression container:
so the formatter never reaches a stable output and the embedding harness bails out.
Cause
<pre>element bodies indprint-plugin-typescriptare emitted verbatim as raw text instead of going throughgen_jsx_with_opening_and_closing. That bypass skips the bookkeeping that marks comments inside the body as handled, so whengen_nodeis later called for the closing</pre>tag, the{/* … */}comment is picked up again byleading_comments_with_previousand emitted a second time as a leading comment of the closing tag.Fix
The fix is in
dprint-plugin-typescript(dprint/dprint-plugin-typescript#796): in the<pre>branch ofgen_jsx_element, advance the comment tracker past the body range and mark every comment it visited as handled. The closing tag's leading-comment pass then finds nothing left to emit and the format stabilises on the first pass.This PR consumes the upstream fix via a
[patch.crates-io]git entry until it ships in a new crates.io release; the patch can be replaced with a plain version bump once that release is out.Test plan
tests/specs/fmt/jsx_pre_with_comment/__test__.jsoncuses the exact input from Deno fmt fails (Preact component with comment) #20403 and asserts the formatter produces the same text back.Closes #20403
Closes denoland/divybot#300